package com.rlevin.facade.logging;

import junit.framework.TestCase;
import com.rlevin.facade.logging.LogLevel;

public class LoggingFacadeTest extends TestCase {

	public LoggingFacadeTest(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}

	public void testLoggingFacadeFactory() throws Exception {
		assertEquals(LoggingFacade.class, LoggingFacade.getInstance(LogLevel.NORMAL,"com.me.TestLogging").getClass());
	}
	
	public void testGetLevel () throws Exception {
		LoggingFacade loggingFacade = LoggingFacade.getInstance(LogLevel.NORMAL,"com.me.TestLogging2");
		assertEquals(LogLevel.NORMAL, loggingFacade.getLevel());
	}
	
	public void testSetLevel () throws Exception {
		ILoggingFacade facade = LoggingFacade.getInstance(LogLevel.OFF, "com.me.TestLogging3");
		facade.setLevel(LogLevel.VERBOSE);
		assertEquals(LogLevel.VERBOSE, facade.getLevel());
		facade.setLevel(LogLevel.OFF);
		assertEquals(LogLevel.OFF, facade.getLevel());
		facade.setLevel(LogLevel.NORMAL);
		assertEquals(LogLevel.NORMAL, facade.getLevel());
	}
	
	/**
	 * Tests adding a handler. Note that if one is note passed into the constructor, or,
	 * setHandler is not called subsequently, it defaults to logging to console. 
	 * @throws Exception
	 */
	public void testHandlerConstructorAndSetter() throws Exception {
		try {
			java.util.logging.FileHandler fh = 
				new java.util.logging.FileHandler ("MyLog.log", true);// append is set to true
			fh.setFormatter(new java.util.logging.SimpleFormatter());
			ILoggingFacade facade = LoggingFacade.getInstance(LogLevel.OFF, "com.me.TestLogging3",fh);
			facade.setHandler(fh);
		}
		catch (java.io.IOException e) {
			e.printStackTrace();
		}
	} 

	public void testAddingCustomHandler () throws Exception {
		ILoggingFacade facade = LoggingFacade.getInstance(LogLevel.NORMAL,"com.me.TestLogging4");
		facade.addCustomHandlerForUnitTesting();
		String msg = "Hello Buddy!\n";
		String msg2 = "How ya doing?";
		facade.logNormal(msg);
		facade.logNormal(msg2);
		assertEquals((msg+msg2), facade.getMessagesLogged());
	}
	
	// TODO: Refactor out into smaller more specific tests!
	public void testUsingLogLevels() throws Exception {
		ILoggingFacade facadeOff = LoggingFacade.getInstance(LogLevel.OFF, "com.OFF");
		facadeOff.addCustomHandlerForUnitTesting();
		String msg = "Hello Buddy!";
		facadeOff.logNormal(msg);
		assertEquals("", facadeOff.getMessagesLogged());
		
		ILoggingFacade facadeNormal = LoggingFacade.getInstance(LogLevel.NORMAL, "com.NORMAL");
		facadeNormal.addCustomHandlerForUnitTesting();
		facadeNormal.logNormal(msg);
		assertEquals(msg, facadeNormal.getMessagesLogged());
		
		ILoggingFacade facadeWarning = LoggingFacade.getInstance(LogLevel.WARNING, "com.WARNING");
		facadeWarning.addCustomHandlerForUnitTesting();
		facadeWarning.logWarning(msg);
		assertEquals(msg, facadeWarning.getMessagesLogged());
		
		ILoggingFacade facadeVerbose = LoggingFacade.getInstance(LogLevel.VERBOSE, "com.VERBOSE");
		facadeVerbose.addCustomHandlerForUnitTesting();
		facadeVerbose.logVerbose(msg);
		assertEquals(msg, facadeVerbose.getMessagesLogged());
	}
	
	public void testCustomHandlerForUnitTestingNotCalledFirstException() throws Exception {
		try {
			ILoggingFacade facade = LoggingFacade.getInstance(LogLevel.NORMAL,"com.me.TestLogging6");
			facade.getMessagesLogged();
			fail("Should have thrown CustomHandlerForUnitTestingNotCalledFirstException.");
		} catch (Exception e) {
			assertEquals(CustomHandlerForUnitTestingNotCalledFirstException.class, e.getClass());
		}
		
	}
}
